Warn about cargo installing the cwd in 2018 edition
authorDale Wijnand <dale.wijnand@gmail.com>
Tue, 10 Apr 2018 00:37:12 +0000 (01:37 +0100)
committerDale Wijnand <dale.wijnand@gmail.com>
Tue, 10 Apr 2018 00:37:12 +0000 (01:37 +0100)
Fixes #5327

src/bin/commands/install.rs
src/cargo/core/source/source_id.rs
src/cargo/ops/cargo_install.rs
tests/testsuite/install.rs

index a353a28217e43edd950430bf8fcde3bb44d800eb..ae4e4bda26a4bae4f701dcf388e690021685b438 100644 (file)
@@ -94,7 +94,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
     } else if let Some(path) = args.value_of_path("path", config) {
         SourceId::for_path(&path)?
     } else if krates.is_empty() {
-        SourceId::for_path(config.cwd())?
+        SourceId::from_cwd(config.cwd())?
     } else {
         SourceId::crates_io(config)?
     };
index c956867b3687023bc3fafaf89ff398c61a415b29..96f5ff6607737f4b1a2a47431695dfabf058b143 100644 (file)
@@ -34,9 +34,10 @@ struct SourceIdInner {
     precise: Option<String>,
     /// Name of the registry source for alternative registries
     name: Option<String>,
+    from_cwd: bool,
 }
 
-/// The possible kinds of code source. Along with a URL, this fully defines the
+/// The possible kinds of code source. Along with SourceIdInner this fully defines the
 /// source
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 enum Kind {
@@ -75,6 +76,7 @@ impl SourceId {
                 url,
                 precise: None,
                 name: None,
+                from_cwd: false,
             }),
         };
         Ok(source_id)
@@ -165,6 +167,20 @@ impl SourceId {
         SourceId::new(Kind::Directory, url)
     }
 
+    pub fn from_cwd(path: &Path) -> CargoResult<SourceId> {
+        let url = path.to_url()?;
+        Ok(SourceId {
+            inner: Arc::new(SourceIdInner {
+                kind: Kind::Path,
+                canonical_url: git::canonicalize_url(&url)?,
+                url,
+                precise: None,
+                name: None,
+                from_cwd: true,
+            }),
+        })
+    }
+
     /// Returns the `SourceId` corresponding to the main repository.
     ///
     /// This is the main cargo registry by default, but it can be overridden in
@@ -200,6 +216,7 @@ impl SourceId {
                 url,
                 precise: None,
                 name: Some(key.to_string()),
+                from_cwd: false,
             }),
         })
     }
@@ -239,6 +256,11 @@ impl SourceId {
         }
     }
 
+    /// Is this source from the current working directory
+    pub fn is_from_cwd(&self) -> bool {
+        self.inner.from_cwd
+    }
+
     /// Creates an implementation of `Source` corresponding to this ID.
     pub fn load<'a>(&self, config: &'a Config) -> CargoResult<Box<super::Source + 'a>> {
         trace!("loading SourceId; {}", self);
index 232c804e8f5c2ef611c781156f796eacebd2965b..2cd7feb32ea4ef44eb06a551bdaac3e77cb02ef4 100644 (file)
@@ -10,7 +10,7 @@ use semver::{Version, VersionReq};
 use tempfile::Builder as TempFileBuilder;
 use toml;
 
-use core::{Dependency, Package, PackageIdSpec, Source, SourceId};
+use core::{Dependency, Edition, Package, PackageIdSpec, Source, SourceId};
 use core::{PackageId, Workspace};
 use ops::{self, CompileFilter, DefaultExecutor};
 use sources::{GitSource, PathSource, SourceConfigMap};
@@ -229,6 +229,15 @@ fn install_one(
     };
     let pkg = ws.current()?;
 
+    if source_id.is_from_cwd() {
+        match pkg.manifest().edition() {
+            Edition::Edition2015 => (),
+            Edition::Edition2018 => {
+                config.shell().warn("To build the current package use 'cargo build', to install the current package run `cargo install --path .`")?;
+            },
+        }
+    };
+
     config.shell().status("Installing", pkg)?;
 
     // Preflight checks to check up front whether we'll overwrite something.
index 250429e1655efa5b56810c18f7552e760aac3fe5..0429540e783d372cde7c33b50795b44398579cc5 100644 (file)
@@ -3,6 +3,7 @@ use std::fs::{self, File, OpenOptions};
 use std::io::prelude::*;
 
 use cargo::util::ProcessBuilder;
+use cargotest::ChannelChanger;
 use cargotest::install::{cargo_home, has_installed_exe};
 use cargotest::support::git;
 use cargotest::support::paths;
@@ -1013,6 +1014,37 @@ fn installs_from_cwd_by_default() {
     assert_that(cargo_home(), has_installed_exe("foo"));
 }
 
+#[test]
+fn installs_from_cwd_with_2018_warnings() {
+    if !cargotest::is_nightly() {
+        // Stable rust won't have the edition option.  Remove this once it
+        // is stabilized.
+        return;
+    }
+    let p = project("foo")
+        .file(
+            "Cargo.toml",
+            r#"
+            [package]
+            name = "foo"
+            version = "0.1.0"
+            authors = []
+        "#,
+        )
+        .file("src/main.rs", "fn main() {}")
+        .build();
+
+    assert_that(
+        cargo_process("install").cwd(p.root()).masquerade_as_nightly_cargo(),
+        execs().with_status(0).with_stderr_contains(
+            "\
+warning: To build the current package use 'cargo build', to install the current package run `cargo install --path .`
+",
+        ),
+    );
+    assert_that(cargo_home(), has_installed_exe("foo"));
+}
+
 #[test]
 fn do_not_rebuilds_on_local_install() {
     let p = project("foo")